package com.zlyx.easy.swagger.config;

import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.model.Developer;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.zlyx.easy.core.collections.Lists;
import com.zlyx.easy.core.tool.StringFormat;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

@Configuration
@EnableOpenApi
@ConfigurationProperties(prefix = "easy.swagger")
public class Swagger3Config implements BeanFactoryAware, InitializingBean {

	private DefaultListableBeanFactory listableBeanFactory;

	@Autowired(required = false)
	private List<SwaggerProperties> properties = new ArrayList<>();

	public List<SwaggerProperties> getProperties() {
		return properties;
	}

	public void setProperties(List<SwaggerProperties> properties) {
		this.properties = properties;
	}

	public Docket createDocket(SwaggerProperties properties) {
		ApiInfo apiInfo = new ApiInfoBuilder().build();
		try {
			MavenXpp3Reader reader = new MavenXpp3Reader();
			String myPom = System.getProperty("user.dir") + File.separator + "pom.xml";
			if (new File(myPom).exists()) {
				Model model = reader.read(new FileReader(myPom));
				List<String> developers = Lists.newList();
				List<String> emails = Lists.newList();
				List<String> urls = Lists.newList();
				if (!model.getDevelopers().isEmpty()) {
					List<Developer> developerList = model.getDevelopers();
					for (Developer developer : developerList) {
						developers.add(developer.getName());
						emails.add(developer.getEmail());
						urls.add(developer.getUrl());
					}
				}
				Contact contact = new Contact(StringFormat.format(developers, ", "), StringFormat.format(emails, ", "),
						StringFormat.format(urls, ", "));
				apiInfo = new ApiInfoBuilder().title(model.getArtifactId()).description(model.getDescription())
						.termsOfServiceUrl(model.getUrl()).version(model.getVersion()).contact(contact).build();
			}
		} catch (Exception e) {

		}
		return new Docket(DocumentationType.OAS_30).groupName(properties.getGroupName()).apiInfo(apiInfo).select()
				.apis(RequestHandlerSelectors.basePackage(properties.getGroupPackage()))
				.paths(PathSelectors.ant(properties.getGroupPath())).build();
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// 如果没有任何Swagger配置，使用默认配置
		if (properties.isEmpty()) {
			properties = Arrays.asList(SwaggerProperties.DEFAULT);
		}
		for (SwaggerProperties swaggerProperties : properties) {
			if (!listableBeanFactory.containsBean(swaggerProperties.getGroupName())) {
				listableBeanFactory.registerSingleton(swaggerProperties.getGroupName(),
						createDocket(swaggerProperties));
			}
		}
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		listableBeanFactory = (DefaultListableBeanFactory) beanFactory;
	}

	@Bean
	public SwaggerProperties config() {
		return SwaggerProperties.DEFAULT;
	}

}
